package jhc.cn.moviegallery;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by luyanfei on 16-11-23.
 */

public class MovieGalleryFragment extends Fragment {

    private static final String TAG = "MovieGalleryFragment";

    private RecyclerView recyclerView;
    private List<GalleryItem> items = new ArrayList<>();
    private ThumbnailDownloader<MovieHolder> thumbnailDownloader;

    public static MovieGalleryFragment newInstance() {
        return new MovieGalleryFragment();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        setHasOptionsMenu(true);
        updateItems();

//        PollService.setServiceAlarm(getActivity(), true);

        Handler responseHandler = new Handler();
        thumbnailDownloader = new ThumbnailDownloader<>(responseHandler);
        thumbnailDownloader.setListener(new ThumbnailDownloader.ThumbnailDownloaderListener<MovieHolder>() {
            @Override
            public void onThumbnailDownloaded(MovieHolder target, Bitmap thumbnail) {
                Drawable drawable = new BitmapDrawable(getResources(), thumbnail);
                target.bindDrawable(drawable);
            }
        });
        thumbnailDownloader.start();
        //等待Looper初始化完成，没有调用getLooper()之前，不能保证onLooperPrepared()会被调用。
        thumbnailDownloader.getLooper();
        Log.i(TAG, "Background thread ThumbnailDownloader started.");
    }

    private void updateItems() {
        String query = QueryPreferences.getStoredQuery(getActivity());
        new FetchItemTask(query).execute();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_movie_gallery, container, false);
        recyclerView = (RecyclerView) view.findViewById(R.id.movie_gallery_recycler_view);
        recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 3));

        setupAdapter();

        return view;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        //当手机切换横竖屏方式时，Activity会重建，ThumbnailDownloader中的MovieHolder会失效，
        // 因此要保证在销毁Fragment时，清空ThumbnailDownloader中的消息。
        thumbnailDownloader.clearQueue();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        thumbnailDownloader.quit();
        Log.i(TAG, "Background thread ThumbnailDownloader destroyed.");
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.fragment_movie_gallery, menu);

        MenuItem item = menu.findItem(R.id.menu_item_search);
        final SearchView searchView = (SearchView) item.getActionView();
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                Log.i(TAG, "Query text submit: " + query);
                QueryPreferences.setStoredQuery(getActivity(), query);
                updateItems();
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                Log.i(TAG, "Query text changed: " + newText);
                return false;
            }
        });

        searchView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String query = QueryPreferences.getStoredQuery(getActivity());
                searchView.setQuery(query, false);
            }
        });

        MenuItem pollingItem = menu.findItem(R.id.menu_item_toggle_polling);
        int pollingItemTitle = PollService.isServiceAlarmOn(getActivity()) ?
                R.string.stop_polling : R.string.start_polling;
        pollingItem.setTitle(pollingItemTitle);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_item_clear:
                QueryPreferences.setStoredQuery(getActivity(), null);
                updateItems();
                return true;
            case R.id.menu_item_toggle_polling:
                boolean shouldStart = !PollService.isServiceAlarmOn(getActivity());
                Log.d(TAG, "toggle polling is selected. shouldStart is: " + shouldStart);
                PollService.setServiceAlarm(getActivity(), shouldStart);
                //刷新工具样菜单，从而更新toggle item的标题。
                getActivity().invalidateOptionsMenu();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private void setupAdapter() {
        //保证fragment已经联接到Activity上，MovieAdapter中调用getActivity()不会得到null.
        if(isAdded()) {
            recyclerView.setAdapter(new MovieAdapter(items));
        }
    }

    private class FetchItemTask extends AsyncTask<Void, Void, List<GalleryItem>> {

        private final String mQuery;

        public FetchItemTask(String query) {
            this.mQuery = query;
        }

        @Override
        protected List<GalleryItem> doInBackground(Void... params) {
            if(mQuery == null) {
                return new DoubanFetchr().fetchInTheaters();
            } else {
                return new DoubanFetchr().searchMovies(mQuery);
            }
        }

        @Override
        protected void onPostExecute(List<GalleryItem> galleryItems) {
            items = galleryItems;
            setupAdapter();
        }
    }

    private class MovieHolder extends RecyclerView.ViewHolder
            implements View.OnClickListener{
        private ImageView imageView;
        private GalleryItem galleryItem;

        public MovieHolder(View itemView) {
            super(itemView);
            imageView = (ImageView) itemView;
            imageView.setOnClickListener(this);
        }

        public void bindDrawable(Drawable drawable) {
            imageView.setImageDrawable(drawable);
        }

        public void bindGalleryItem(GalleryItem item) {
            this.galleryItem = item;
        }

        @Override
        public void onClick(View v) {
            Intent intent = MoviePageActivity.newIntent(getActivity(), Uri.parse(galleryItem.getUrl()));
            startActivity(intent);
        }
    }

    private class MovieAdapter extends RecyclerView.Adapter<MovieHolder> {

        private List<GalleryItem> galleryItems;

        public MovieAdapter(List<GalleryItem> galleryItems) {
            this.galleryItems = galleryItems;
        }

        @Override
        public MovieHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(getActivity());
            View view = inflater.inflate(R.layout.gallery_item, parent, false);
            return new MovieHolder(view);
        }

        @Override
        public void onBindViewHolder(MovieHolder holder, int position) {
            Drawable placeholder = getResources().getDrawable(R.mipmap.ic_launcher);
            holder.bindDrawable(placeholder);
            GalleryItem item = galleryItems.get(position);
            holder.bindGalleryItem(item);
            thumbnailDownloader.queueThumbnail(holder, item.getImageUrl());
        }

        @Override
        public int getItemCount() {
            return this.galleryItems.size();
        }
    }
}
